using System;
using System.Collections.Generic;
using System.Text;
using FutureOpen.Core.func.analyzer;
using Lucene.Net.Search;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Documents;
using Lucene.Net.Analysis;

namespace FutureOpen.Core.func.search
{
     public class ArtHandler
    {
        public static BooleanClause.Occur[] flags = { BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD };
         public static String[] fields = new String[] { FieldNames.FIELD_ART_TITLE, FieldNames.FIELD_ART_CONTENT };
        
        private Query query = null;
        private ShootAnalyzer analyzer = null;
        private HighLightUtil lighter = null;
        private float searchTime;
        private Hits hitResults = null;
        private static readonly int TICK_UNIT = 1000000;
        private static readonly int DEFAULT_SIZE = 100;

         private ArtResult[] items = new ArtResult[DEFAULT_PAGE_COUNT * DEFAULT_PAGE_SIZE];
        public static readonly int DEFAULT_PAGE_SIZE = 10;
        public static readonly int DEFAULT_PAGE_COUNT = 10;

        private int pageSize = DEFAULT_PAGE_SIZE;
        private int totalHits;

        private int curPage = 1;
        private int totalPage = 1;


        public float GetTime()
        {
            return this.searchTime;
        }

        public int GetCount()
        {
            return this.hitResults.Length();
        }
        public int GetCurrentPageNum()
        {
            return this.curPage;
        }

        public int GetLastPageNum()
        {
            return this.totalPage;
        }

         public static ArtHandler DoCustomSearchyByRel(Query query, Filter filter)
        {
            long time = DateTime.Now.Ticks;
            Hits hits = null;
            IndexReader reader = IndexManager.GetArtIndexReader();
            if (filter == null)
            {
                hits = LuceneSearch.SearchByRel(reader, query);
            }
            else
            {
                hits = LuceneSearch.SearchByRel(reader, query, filter);
            }

            float searchTime = (float)(DateTime.Now.Ticks - time) / TICK_UNIT;

            return new ArtHandler(query, new ShootAnalyzer(), hits, searchTime);
        }

         public static ArtHandler DoCustomSearchyByTime(Query query, Filter filter)
        {
            long time = DateTime.Now.Ticks;
            Hits hits = null;
            IndexReader reader = IndexManager.GetArtIndexReader();
            if (filter == null)
            {
                hits = LuceneSearch.SearchByTime(reader, query);
            }
            else
            {
                hits = LuceneSearch.SearchByTime(reader, query, filter);
            }

            float searchTime = (float)(DateTime.Now.Ticks - time) / TICK_UNIT;

            return new ArtHandler(query, new ShootAnalyzer(), hits, searchTime);
        }

        private ArtHandler(Query query, ShootAnalyzer analyzer,
                         Hits hits,
                        float searchTime)
        {

            this.query = query;
            this.analyzer = analyzer;
            this.query = query;
            this.lighter = new HighLightUtil(this.query);
            this.searchTime = searchTime;
            this.totalHits = hits.Length();
            this.hitResults = hits;


            this.totalPage = (int)Math.Floor((float)this.totalHits / this.pageSize);
            if (this.totalPage == 0)
            {
                this.totalPage = 1;
            }

        }

        private void CheckSize(int page)
        {

            if (this.pageSize * page > items.Length
                && this.items.Length < this.totalHits)
            {
                int orginSize = items.Length;

                ArtResult[] orginItems = this.items;
                this.items = new ArtResult[this.totalHits];

                Array.Copy(orginItems, this.items, orginItems.Length);
            }
        }

        public ArtResult[] GetPage(int i)
        {
            if (i >= 1 && i <= this.totalPage)
            {
                this.curPage = i;
                return this.GetItemsByPage(i);
            }
            return GetItemsByPage(this.totalPage);
        }
        public ArtResult[] GetFirstPage()
        {
            return this.GetItemsByPage(1);
        }

        public ArtResult[] GetLastPage()
        {
            return this.GetItemsByPage(totalPage);
        }

        public ArtResult[] GetCurrentPage()
        {
            return GetItemsByPage(this.curPage);
        }


        private ArtResult[] GetItemsByPage(int page)
        {
            ArtResult[] currengPage = new ArtResult[this.pageSize];
            CheckSize(page);
            int index = (page - 1) * this.pageSize;
            for (int i = 0; i < this.pageSize; i++)
            {
                int curIndex = i + index;
                if (curIndex >= this.totalHits)
                {
                    break;
                }

                if ((this.items[curIndex] == null))
                {
                    this.items[curIndex] = new ArtResult(this.hitResults.Id(curIndex));
                    this.items[curIndex].Fetch(this.lighter);
                }

                currengPage[i] = this.items[i + index];
            }
            return currengPage;
        }

    }
}
